﻿// Inner Fire 游戏引擎库
// DxMeshFactory - Mesh工场
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 用于生成与保存最简单的Mesh。比如线段，Quad。
// 使用一个假的Singlton模式。实际上的项目在DxGraphics中。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-05-23

#pragma once

#include <EASTL/unordered_map.h>
#include <EASTL/vector.h>
#include <dx/mesh/dx_mesh.h>
#include <graphics/vertex.h>
#include <memory>
#include <static_string.h>

namespace ifire::dx {
class DxMeshFactory {
public:  
  // 私有构造函数
  DxMeshFactory() = default;
  // 删除拷贝构造函数和赋值运算符
  DxMeshFactory(const DxMeshFactory&) = delete;
  DxMeshFactory& operator=(const DxMeshFactory&) = delete;
  ~DxMeshFactory() = default;

  // 获取单例实例
  static DxMeshFactory& GetInstance() {
    return *instance;
  }
  static void SetInstance(DxMeshFactory* factory) {
    instance = factory;
  }

  // 进行初始化
  void CreateSystemMesh(ID3D12Device* device, ID3D12GraphicsCommandList* cmd);

  // 创建一个对象
  template <typename T>
  DxMesh* CreateMesh(ikit::sstr name, const eastl::vector<T>& vertices,
      const eastl::vector<uint16_t>& indices);

  // 获取网格（不转移所有权）
  DxMesh* GetMesh(ikit::sstr name) const;
  // 清空所有网格（通常在设备丢失时调用）
  void Clear() { meshes_.clear(); }

  // ------
  // 属性访问
  // ------
  DxMesh* GetCube() const { return mesh_cube_; }
  DxMesh* GetQuad() const { return mesh_quad_; }
  DxMesh* GetDualQuad() const { return mesh_dual_quad_; }
  DxMesh* GetUIQuad() const { return ui_quad_; }
  DxMesh* GetLine() const { return mesh_line_; }

private:
  static DxMeshFactory* instance;

  // 网格资源存储
  // TIPS:自从创建了这个类之后，一直会导致这个Mesh无法释放。在Exit程序的时候，经常会出问题。
  // 但是仅仅是编译之后，第一次运行出问题。之后却不会出问题，非常诡异，但是要记住这个。
  eastl::unordered_map<size_t, DxMesh*> map_;
  eastl::vector<std::unique_ptr<DxMesh>> meshes_;

  // 系统常用的MESH
  DxMesh* mesh_cube_;
  DxMesh* mesh_quad_;
  DxMesh* mesh_dual_quad_;
  DxMesh* ui_quad_;
  DxMesh* mesh_line_;

  // 用于临时存储，不用在函数调用中每次传递
  ID3D12Device* device_;
  ID3D12GraphicsCommandList* cmd_;
};
} // namespace ifire::dx